package com.gitee.deeround.javaprotect.tool.util;

import com.gitee.deeround.javaprotect.tool.JarFileInfo;
import com.gitee.deeround.javaprotect.tool.ProtectException;
import javassist.ClassPool;
import javassist.CtClass;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CommonUtils {
    public static String getPath(String path) {
        try {
            if (path == null) {
                path = CommonUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath();
            }
            return URLDecoder.decode(path, "utf-8");
        } catch (Exception e) {
            throw new ProtectException(e);
        }
    }

    public static void loadClassPath(ClassPool pool, List<JarFileInfo> files) {
        try {
            List<String> classPathDirs = new ArrayList<>();
            for (JarFileInfo file : files) {
                if (file.getFileName().endsWith(".jar")) {
                    pool.appendClassPath(file.FilePath);
                }
                if (file.getFileName().endsWith(".class")) {
                    String dir = file.getClassPath();
                    if (!classPathDirs.contains(dir)) {
                        classPathDirs.add(dir);
                        pool.appendClassPath(dir);
                    }
                }
            }

        } catch (Exception e) {
            throw new ProtectException(e);
        }
    }

    public static CtClass loadClass(ClassPool pool, byte[] clsBytes) {
        try {
            try (ByteArrayInputStream stream = new ByteArrayInputStream(clsBytes)) {
                CtClass ctClass = pool.makeClass(stream);
                return ctClass;
            }
        } catch (Exception e) {
            throw new ProtectException(e);
        }
    }

    public static String getJarUnJarPath(String jarPath) {
        return jarPath + JarUtils.JARUNJARTAG;
    }

    public static String getClassEncodePath(String targetDir, String className) {
        String path = "/META-INF/.protect/" + className;
        if (targetDir == null) {
            return path;
        }
        return new File(targetDir, path).getAbsolutePath();
    }

    public static Map<String, String> parse(String... args) {
        Map<String, String> ps = new HashMap<>();
        if (args == null || args.length == 0) {
            return ps;
        }

        for (int i = 0; i < args.length; i++) {
            String k = args[i];
            if (k.startsWith("--")) {
                String v = args[i + 1];
                ps.put(k.substring(2), v.startsWith("--") ? null : v);
            }
        }

        return ps;
    }

    public static String getMD5(String input) {
        try {
            // 获取一个MD5算法的MessageDigest实例
            MessageDigest md = MessageDigest.getInstance("MD5");

            // 计算输入字符串的MD5值
            byte[] messageDigest = md.digest(input.getBytes());

            // 创建16进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte aMessageDigest : messageDigest) {
                String shaHex = Integer.toHexString(aMessageDigest & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            //e.printStackTrace();
        }
        return input;
    }
}
